package algorithm.leetcode;

import java.time.Instant;
import java.time.temporal.ChronoUnit;

/**
 * @author wuwen
 * @since 2023/12/6
 */
public class NO0_不用加号的加法 {
    public static void main(String[] args) {
        Instant start = Instant.now();
        SolutionPerformance solutionPerformance = new SolutionPerformance();
        System.out.println(solutionPerformance.add(-1, 2));
        Instant end = Instant.now();
        long costTime = ChronoUnit.NANOS.between(start, end);
        System.out.println(costTime);
    }

    static class SolutionPerformance {
        /**
         * 当位的加法是异或，当位的进位是与
         * 右移是因为每一次进位的话，会直接放到原本数字的当前位置上，所以需要右移来进行一次偏移。
         * 第一次没有偏移量则是因为没有当时的进位都是零，所以现在理解了之后来自己实现一下吧。
         */
        public int add(int a, int b) {
            while (b != 0) {
                int temp = a ^ b; //先算除每次不考虑进位的结果
                b = (a & b) << 1;
                a = temp;
            }
            return a;
        }
    }

    static class SolutionHalfError {
        public int add(int a, int b) {
            int offset = 0, carryBit = 0, result = 0;
            int active, passive;
            while (a != 0 || b != 0 || carryBit != 0) {
                active = (a & 1) << offset;
                passive = (b & 1) << offset;
                result |= (active ^ passive ^ carryBit);
                carryBit = calculateBit(new int[]{active, passive, carryBit});
                offset++;
                carryBit <<= offset;
                a >>= 1;
                b >>= 1;
            }
            return result;
        }
        private int calculateBit(int[] test) {
            int counterOne = 0;
            for (int i : test) {
                String bin = Integer.toBinaryString(i);
                counterOne += bin.length() - bin.replaceAll("1", "").length();
            }
            return counterOne >= 2 ? 1 : 0;
        }
    }
}

